using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Drawing.Imaging;

namespace SpaceDesigner
{
    public partial class MainForm : Form
    {
        #region Fields

        private bool isSaved = false;

        private string fileName = "";

        private Color backgroundColor = Color.Black;

        #endregion

        #region Properties

        private Bitmap picture = null;
        public Bitmap Picture
        {
            get { return picture; }
            set { picture = value; }
        }

        #endregion

        #region Construction/destruction

        public MainForm()
        {
            InitializeComponent();
        }

        #endregion

        #region Events Handlers

        private void newToolStripMenuItem_Click(object sender, EventArgs e)
        {
            NewPictureFrm npf = new NewPictureFrm();

            if(DialogResult.OK == npf.ShowDialog())
            {
                picture = new Bitmap(npf.PictureWidth, npf.PictureHeight);
                isSaved = false;
                fileName = ("" == npf.Title ? "NewPicture" : npf.Title);
                backgroundColor = npf.BackgroundColor;

                Graphics g = Graphics.FromImage(picture);

                g.FillRectangle(new SolidBrush(backgroundColor), 0, 0, picture.Width, picture.Height);
                g.Dispose();

                if ("" != npf.StarPatternFile)
                {
                    DrawStars(picture, npf.StarPatternFile, npf.StarCount);
                }

                if ("" != npf.CloudPatternFile)
                {
                    DrawCloud(picture, npf.CloudPatternFile);
                }

                pictureBox1.SizeMode = PictureBoxSizeMode.AutoSize;
                pictureBox1.Image = picture;
            }
        }

        private void saveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SaveFileDialog sfd = new SaveFileDialog();

            sfd.DefaultExt = "bmp";

            sfd.FileName = fileName;

            if (DialogResult.OK == sfd.ShowDialog())
            {
                picture.Save(sfd.FileName);
                isSaved = true;
            }
        }

        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();

            ofd.Filter = "Bitmap (*.bmp)|*.bmp";

            if(DialogResult.OK == ofd.ShowDialog())
            {
                picture = new Bitmap(ofd.FileName);
                string[] s = ofd.FileName.Split('\\');
                string[] file = s[s.Length - 1].Split('.');

                fileName = file[0];

                pictureBox1.SizeMode = PictureBoxSizeMode.AutoSize;
                pictureBox1.Image = picture;
            }
        }

        #endregion

        #region Methods

        public void DrawStars(Image img, string starFile, int starCount)
        {
            Graphics gr = Graphics.FromImage(img);
            Random newPosition = new Random();

            Bitmap temp = new Bitmap(starFile);
            for (int i = 0; i < starCount; i++)
            {
                gr.DrawImage(ImageManager.ScaleByPercent(temp, newPosition.Next(0, 45)), newPosition.Next(0, img.Width), newPosition.Next(0, img.Height));
            }
        }

        public void DrawCloud(Image img, string cloudFile)
        {
            Random newPosition = new Random();
            Graphics gr = Graphics.FromImage(img);

            Bitmap temp = new Bitmap(cloudFile);

            for (int i = 0; i < 5; i++)
            {

                Bitmap tempBM = (Bitmap)ImageManager.ScaleByPercent(temp, newPosition.Next(75, 700));
                tempBM.MakeTransparent(Color.Black);
                tempBM = OpacityImage(tempBM, (float)0.5);

                gr.DrawImage(tempBM, newPosition.Next(0, img.Width), newPosition.Next(0, img.Height));
            }

        }

        public Bitmap OpacityImage(Bitmap original, float opacity)
        {
            Bitmap temp = new Bitmap(original.Width, original.Height);
            Graphics g = Graphics.FromImage(temp);
            ColorMatrix cm = new ColorMatrix();
            cm.Matrix33 = opacity;

            ImageAttributes ia = new ImageAttributes();
            ia.SetColorMatrix(cm, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
            g.DrawImage(original, new Rectangle(0, 0, temp.Width, temp.Height), 0, 0, original.Width, original.Height, GraphicsUnit.Pixel, ia);
            g.Dispose();

            return temp;
        }

        public Image CreateSphere(Bitmap bmp)
        {
            Bitmap img = new Bitmap(bmp);
            int imgOutLen = img.Width * img.Height;

            int[] imageoutR = new int[imgOutLen];
            int[] imageoutG = new int[imgOutLen];
            int[] imageoutB = new int[imgOutLen];

            int x, y, r, g, b, a, x2, indx;

            double i, j, theta, phi, phi2;

            indx = 0;

            for (y = 0; y < img.Height - 1; y++)
            {
                theta = Math.PI * (y - (img.Height - 1) / 2.0) / (img.Height - 1);

                for (x = 0; x < img.Width - 1; x++)
                {
                    phi = Math.PI * 2 * (x - img.Width / 2.0) / img.Width;
                    phi2 = phi * Math.Cos(theta);
                    x2 = Convert.ToInt32(phi2 * img.Width / (Math.PI * 2) + img.Width / 2);

                    if ((x2 < 0) || (x2 > img.Width - 1))
                    {
                        // something bad happened - flag as red? - Should never happen 
                        r = 1;
                        g = 0;
                        b = 0;
                    }
                    else
                    {
                        Color clr = img.GetPixel(x2, y);
                        r = clr.R;
                        g = clr.G;
                        b = clr.B;
                    }


                    // temporarily store the pixel in the out buffers
                    imageoutR[indx] = r;
                    imageoutG[indx] = g;
                    imageoutB[indx] = b;

                    indx = indx + 1;     // optimized for speed
                }

                //progress(y / height);
            }

            indx = 0; //                    -- optimized for better speed
            for (y = 0; y < img.Height - 1; y++)
            {
                for (x = 0; x < img.Width - 1; x++)
                {
                    r = imageoutR[indx];
                    g = imageoutG[indx];
                    b = imageoutB[indx];

                    img.SetPixel(x, y, Color.FromArgb(r, g, b));

                    indx = indx + 1;          //-- optimized for better speed

                }
                //progress(y / height)
            }

            return img;
        }

        #endregion

        private void createSphereToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Image img = CreateSphere(this.picture);

            SaveFileDialog sfd = new SaveFileDialog();

            sfd.DefaultExt = "bmp";

            sfd.FileName = fileName + "_sphere";

            if (DialogResult.OK == sfd.ShowDialog())
            {
                img.Save(sfd.FileName);
            }
        }
    }
}